package com.logic.landseaserver.service.impl;

import java.util.Date;
import java.util.List;

import com.logic.landseaserver.ws.dto.ContractDTO;
import com.logic.landseaserver.ws.dto.DepositDTO;
import com.logic.system.service.IConfigurationService;
import com.logic.system.service.impl.ConfigurationService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.common.domain.Code;
import com.logic.common.exception.BusinessException;
import com.logic.common.util.QueryUtil;
import com.logic.landseaserver.common.LandeaConstants.SignType;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.config.SendMsgConfiguration;
import com.logic.landseaserver.common.enums.SendMsgCodeEnum;
import com.logic.landseaserver.common.exception.LandseaBusinessException;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.common.util.RandomUtil;
import com.logic.landseaserver.common.util.SMSUtil;
import com.logic.landseaserver.common.util.StringTools;
import com.logic.landseaserver.domain.Contract;
import com.logic.landseaserver.domain.Deposit;
import com.logic.landseaserver.domain.Message;
import com.logic.landseaserver.domain.VerificationCode;
import com.logic.landseaserver.persistence.read.ContractReadMapper;
import com.logic.landseaserver.persistence.read.DepositReadMapper;
import com.logic.landseaserver.persistence.read.VerificationCodeReadMapper;
import com.logic.landseaserver.persistence.write.VerificationCodeWriteMapper;
import com.logic.landseaserver.service.IMessageService;
import com.logic.landseaserver.service.IOrderService;
import com.logic.landseaserver.service.ISendSmsService;
import com.logic.landseaserver.ws.request.GetSendSmsReq;
import com.logic.system.service.ICodeService;

@Service
public class SendSmsServiceImpl implements ISendSmsService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    private VerificationCodeWriteMapper vCodeWriteMapper;

    @Autowired
    private VerificationCodeReadMapper vCodeReadMapper;

    @Autowired
    private SendMsgConfiguration sendMsgConfiguration;

    @Autowired
    private IMessageService messageService;

    @Autowired
    private ICodeService codeService;

    @Autowired
    private IConfigurationService configurationService;

    @Autowired
    private DepositReadMapper depositReadMapper;
    
    @Autowired
    private ContractReadMapper contractReadMapper;


    @Override
    public int insert(Object obj) throws LandseaBusinessException {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Object get(Integer id) throws LandseaBusinessException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void update(Object obj) throws LandseaBusinessException {
        // TODO Auto-generated method stub

    }

    @Override
    public void delete(String ids) throws LandseaBusinessException {
        // TODO Auto-generated method stub

    }

    @Override
    public List<Object> query(QueryUtil queryUtil) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean validate(Object obj) throws LandseaBusinessException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean validateForInsert(Object obj) throws LandseaBusinessException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean validateForUpdate(Object obj) throws LandseaBusinessException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean validateForDelete(Object obj) throws BusinessException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void checkVerification(VerificationCode verification) throws LandseaBusinessException {
        //万能验证码 update by Daniel on 20171212
        //String allVerifyCode = sendMsgConfiguration.getVerifyCode();
        String allVerifyCode = configurationService.getStringValue(ConfigurationService.UNIVERSAL_VERIFICATION_CODE);
        if (verification.getVerificationCode().equals(allVerifyCode)) {
            return;
        }

        if (StringUtils.isEmpty(verification.getCellPhone())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_CELLPHONE_ISNULL);
        }

        if (!StringTools.isPhone(verification.getCellPhone())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_CELLPHONE_ISINVALID);
        }

        if (StringUtils.isEmpty(verification.getOper())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_VCODE_OPR_ISNULL);
        }

        if (StringUtils.isEmpty(verification.getVerificationCode())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_VCODE_ISNULL.getDesc());
        }
        // 判断是否已经获取验证码
        VerificationCode verificationForDb = vCodeReadMapper.selectCodeByCellPhone(verification);
        if (verificationForDb == null) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_VCODE_GETFIRST);
        }
        Date date = new Date();
        if (date.after(verificationForDb.getValidTime())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_VCODE_ERROR);
        }
        if (verificationForDb.getWrongNum() >= 5) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_VCODE_MORETIME_ERROR);
        }

        VerificationCode newVarification = new VerificationCode();
        newVarification.setId(verificationForDb.getId());
        if (!verification.getVerificationCode().equals(verificationForDb.getVerificationCode())) {
            newVarification.setWrongNum(verificationForDb.getWrongNum() + 1);
            newVarification.setValidTime(verificationForDb.getValidTime());
            vCodeWriteMapper.update(newVarification);
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_VCODE_ERROR.getDesc());
        }
    }

    @Override
    public String sendSms(GetSendSmsReq verifyReq) throws BusinessException {
        VerificationCode vCode = new VerificationCode();
        vCode.setCellPhone(verifyReq.getPhone());
        vCode.setOper(verifyReq.getOper());
        if (StringUtils.isEmpty(vCode.getCellPhone())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_CELLPHONE_ISNULL);
        }

        if (!StringTools.isPhone(vCode.getCellPhone())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_CELLPHONE_ISINVALID);
        }

        if (StringUtils.isEmpty(vCode.getOper())) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_VCODE_OPR_ISNULL);
        }
        int codeNum = RandomUtil.getRandom(100000, 999999);

        //TODO Message Sent Count?
        if (!messageService.queryCountsByPhone(verifyReq.getPhone())) {
            return codeNum + "";
        }
        // 判断是否已经发送过短信
        VerificationCode vCodeInfo = vCodeReadMapper.selectCodeByCellPhone(vCode);
        String messageCode = "";
        String param = "";
        SendMsgCodeEnum oper = null;
        if (SendMsgCodeEnum.order.name().equals(verifyReq.getOper())) {
            oper = SendMsgCodeEnum.order;
            String info[] = verifyReq.getParams().split(",");
            String name = info[0];
            try {
                Code code= codeService.getCode(info[1]);
                if(code != null) {
                    name += code.getCodeDescTr();
                }
            } catch (Exception e){
                logger.error("sendSms error.", e);
            }
            messageCode = sendMsgConfiguration.getOrderMessageCode();
            param = " {'code':'" + codeNum + "'}";
            //${name}，您的验证码是${code}，请在页面中提交验证码完成预约（10分钟内有效）。
        }
        if (SendMsgCodeEnum.register.name().equals(verifyReq.getOper())) {
            oper = SendMsgCodeEnum.register;
            messageCode = sendMsgConfiguration.getRegisterMessageCode();
            param = " {'code':'" + codeNum + "'}";
        }
        if (SendMsgCodeEnum.updatePsd.name().equals(verifyReq.getOper())) {
            oper = SendMsgCodeEnum.updatePsd;
            messageCode = sendMsgConfiguration.getUpdateMsgMessageCode();
            param = " {'code':'" + codeNum + "'}";
        }
        if (SendMsgCodeEnum.deposit.name().equals(verifyReq.getOper())) {
            oper = SendMsgCodeEnum.deposit;
            messageCode = sendMsgConfiguration.getDepositMessageCode();
            param = " {'code':'" + codeNum + "'}";
        }
        if (SendMsgCodeEnum.signConfirmation.name().equals(verifyReq.getOper())) {
            oper = SendMsgCodeEnum.signConfirmation;
            messageCode = sendMsgConfiguration.getSignConfirmationPdfCode();
            
            //${name}您好，您的签约${password}，并请您确认如下信息，姓名：${username}、
            //证件号：${idno}、手机号：${cellPhone}、联系地址：${address}。谢谢！
            String params = verifyReq.getParams();
            String []str = params.split(",");
            Integer id = Integer.parseInt(str[0]);
            Integer type = Integer.parseInt(str[1]);
            if (SignType.DEPOSIT == type.intValue())
            {
                DepositDTO deposit = depositReadMapper.getDepositDetail(id);
                if (null == deposit)
                {
                    throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_COUSTOMER_ISNULL);
                    
                }
                param = " {'code':'" + codeNum + "'}";
               // param = " {'name':'" + deposit.getUserName() + "','code':'" + codeNum + "'}";
            }
            else if (SignType.CONTRACT == type.intValue()) {
                
                ContractDTO contract = contractReadMapper.queryContractDetail(id);
                if (null == contract)
                {
                    throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_COUSTOMER_ISNULL);
                    
                }
                param = " {'code':'" + codeNum + "'}";
            }
        }
        String signName = configurationService.getStringValue(ConfigurationService.SEND_MSG_SIGN_NAME);
        boolean result = SMSUtil.sendSms(messageCode, vCode.getCellPhone(), param,signName);

        if (!result) {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.SMS_GET_REGISTER_VCODE_ISFAIL);
        }

        if (vCodeInfo == null) {
            VerificationCode vCodeForAddMd = new VerificationCode();
            vCodeForAddMd.setCellPhone(vCode.getCellPhone());
            vCodeForAddMd.setOper(vCode.getOper());
            vCodeForAddMd.setWrongNum(0);
            vCodeForAddMd.setVerificationCode(String.valueOf(codeNum));
            vCodeForAddMd.setValidTime(DateUtil.getInstence().getNextMinute(10));
            vCodeForAddMd.updateCommonInfo(null);
            vCodeWriteMapper.insertSelective(vCodeForAddMd);
        } else {
            vCodeInfo.updateCommonInfo(vCodeInfo.getId());
            vCodeInfo.setWrongNum(0);
            vCodeInfo.setVerificationCode(String.valueOf(codeNum));
            vCodeInfo.setValidTime(DateUtil.getInstence().getNextMinute(10));
            vCodeWriteMapper.update(vCodeInfo);
        }
        Message message = new Message();
        message.setType(oper);
        message.setParams(param);
        message.setMobilePhone(vCode.getCellPhone());
        message.setStatus(1);
        message.setSendTime(new Date());
        messageService.insert(message);
        return codeNum + "";

    }


}
